import numpy as np
import pandas as pd

pd1 = pd.Series(np.random.rand(5), index=['a', 'b', 'c', 'd', 'e'])
# 用 Series 字典或字典生成 DataFrame
data1 = {
    'one': pd.Series([1, 2, 3, 4], index=['a', 'b', 'c', 'd']),
    'two': pd.Series([5, 6, 7, 8], index=['a', 'b', 'c', 'd']),
    'three': pd.Series([9, 10, 11, 12], index=['a', 'b', 'c', 'd']),
    'four': pd.Series([13, 14, 15], index=['a', 'b', 'c'])
}
df1 = pd.DataFrame(data1)
df2 = pd.DataFrame(data1, index=['a', 'b'], columns=['two', 'three'])  # 指定索引和列
print(df1)
print(df2)
print(df1.index)
print(df1.columns)
# 用多维数组字典、列表字典生成 DataFrame
data2 = {
    'one': [1, 2, 3, 4],
    'two': [5, 6, 7, 8],
    'three': [9, 10, 11, 12],
    'four': [13, 14, 15, 16]
}
df3 = pd.DataFrame(data2, index=['a', 'b', 'c', 'd'], columns=['one', 'two', 'three', 'four'])
print(df3)
# 用结构多维数组或记录多维数组生成 DataFrame
data3 = np.zeros((2,), dtype=[('A', 'i4'), ('B', 'f4'), ('C', 'a10')])
data3[:] = [(1, 2., 'Hello'), (2, 3., "World")]
pd3 = pd.DataFrame(data3, index=['a', 'b'], columns=['A', 'B', 'C'])
print(pd3)
# 用列表字典生成 DataFrame
data4 = [{'a': 1, 'b': 2, 'c': 3}, {'a': 5, 'b': 6, 'd': 7}]
df4 = pd.DataFrame(data4)
print(df4)
# 用元组字典生成 DataFrame

data5 = {('a', 'b'): {('A', 'B'): 1, ('A', 'C'): 2},
         ('a', 'a'): {('A', 'C'): 3, ('A', 'B'): 4},
         ('a', 'c'): {('A', 'B'): 5, ('A', 'C'): 6},
         ('b', 'a'): {('A', 'C'): 7, ('A', 'B'): 8},
         ('b', 'b'): {('A', 'D'): 9, ('A', 'B'): 10}}
pd5 = pd.DataFrame(data5)
print(pd5)
print(pd5.T)
# 用 Series 创建 DataFrame
data6 = [pd.Series([1, 2, 3, 4], index=['a', 'b', 'c', 'd'], name='one'),
         pd.Series([5, 6, 7, 8], index=['a', 'b', 'c', 'd'], name='two'),
         pd.Series([9, 10, 11, 12], index=['a', 'b', 'c', 'd'], name='three'),
         pd.Series([13, 14, 15], index=['a', 'b', 'c'], name='four')]
df6 = pd.DataFrame(data6)
print(df6)


#备选构建器
#DataFrame.from_dict
pd7=pd.DataFrame.from_dict({'A': [1, 2, 3], 'B': [4, 5, 6], 'C': [7, 8, 9]},orient='index',columns=['one','two','three'])
print(pd7)
#DataFrame.from_records

#提取、添加、删除列
"""
   one  two  three  four
a    1    5      9  13.0
b    2    6     10  14.0
c    3    7     11  15.0
d    4    8     12   NaN
"""
print(df1['one'])
df1['flag']=df1['one']+df1['two']#添加列
print(df1['flag'])
print(df1)
del df1['flag']#删除列
three=df1.pop('three')
print(three)
print(df1)
df1['asdas']='ad'#标量值以广播的方式填充列：
print(df1)
df1['one_copy']=df1['one'][:3]
print(df1)

df1.insert(1, 'bar', df1['one'])#在指定位置插入一列 数组可继承其余列
print(df1)
#用方法链分配新列
df11=df1.assign(spal_ration=df1['one']/df1['two'])#assign 返回的都是数据副本，原 DataFrame 不变。
print(df11)
#query  筛选
print(df1.query('one<3').assign(spal_ration=df1['one']/df1['two']))


dfa = pd.DataFrame({
    'A': [1, 2, 3],
    'B': [4, 5, 6],

})

# 正确的 assign 用法
result = dfa.assign(C=lambda x: x["A"] + x["B"], D=lambda x: x["A"] + x["C"])

# 打印结果
print(result)

#索引 / 选择
print(df1)
print(df1['one'])#选择列
print(df1.loc['a'])#用标签选择行
print(df1.iloc[1])#用整数位置选择行
print(df1[1:2])#行切片
basbda=df1['one']>3# 获取 one 列大于 3 的行
print(df1[basbda])#用布尔向量选择行

#数据对齐和运算
"""
在 Pandas 中，当你对两个 DataFrame 进行逐元素操作（如加法）时，Pandas 会自动对齐这两个 
DataFrame 的索引和列标签。
具体来说，Pandas 会取两个 DataFrame 
的行索引和列标签的并集，
并将缺失的部分填充为 NaN。
这是为了确保操作的完整性和一致性。
"""
df21 = pd.DataFrame(np.random.randn(10, 4), columns=['A', 'B', 'C', 'D'])
df22 = pd.DataFrame(np.random.randn(7, 3), columns=['A', 'B', 'C'])
print(df21 + df22)

print(df21-df21.iloc[0])


print(df21.T)
#DataFrame 应用 NumPy 函数
print(np.exp(df21))

ser = pd.Series([7, 2, 3])
idx = pd.Index([4, 5, 6])

print(np.maximum(ser, idx))
#DataFrame 列属性访问和 IPython 代码补全
print(df21.A)


